#ifndef __ANY_SOCKET__
#define __ANY_SOCKET__

#include <stdbool.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <sys/uio.h>
#include <unistd.h>

#include "st.h"
#include "log.h"
//#include "st-hack.h"

#ifdef __cplusplus
extern "C" {
#endif

#define SOCKET_BUF_SIZE (256*1024)

static inline int enable_tcp_no_delay(int fd)
{
	int state = 1;
	return setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &state, sizeof(state));
}

static inline int enable_tcp_cork(int fd)
{
	int state = 1;
	return setsockopt(fd, IPPROTO_TCP, TCP_CORK, &state, sizeof(state));
}

static inline int disable_tcp_cork(int fd)
{
	int state = 0;
	return setsockopt(fd, IPPROTO_TCP, TCP_CORK, &state, sizeof(state));
}

static inline int set_tcp_wbuf_size(int fd)
{
	return 0;
	unsigned int send_size, optlen;
	int err = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &send_size, &optlen);
	LOG_DEBUG("get socket SO_SNDBUF size is %d set to %d", send_size, SOCKET_BUF_SIZE);
	send_size = SOCKET_BUF_SIZE;
	err = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &send_size, sizeof(send_size));
	if(err < 0){
		LOG_ERROR("error setsockopt SO_SNDBUF %m");
	}
	return err;
}

static inline int set_tcp_rbuf_size(int fd)
{
	return 0;
	unsigned int receive_size, optlen;
	int err = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &receive_size, &optlen);
	LOG_DEBUG("get socket SO_RCVBUF size is %d set to %d", receive_size, SOCKET_BUF_SIZE);
	receive_size = SOCKET_BUF_SIZE;
	err = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &receive_size, sizeof(receive_size));
	if(err < 0){
		LOG_ERROR("error setsockopt SO_RCVBUF %m");
	}
	return err;
}

static inline void flush_tcp(st_netfd_t stfd)
{
	int fd = st_netfd_fileno(stfd);
	disable_tcp_cork(fd);
	enable_tcp_cork(fd);
}

static inline int enable_reuse_addr(int fd)
{
	int state = 1;
	return setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &state, sizeof(state));
}

#ifdef __cplusplus
}
#endif

#endif
